/** Module: base64.d - Base64 encoding processor
  * Authors: Wei Li (oldrev@gmail.com)
  * Copyright: Copyright (C) 2007. All rights reserved.
  * License: BSD
  * Date: May 30 2007
  *
  */

module dotmars.text.base64;

version(none) { 

import dotmars.base.stdexcept;

const char Base64Alpahbets[] = 
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

char[] encode(char[] str, void delegate(char) sink = null)
{
	char[] result = null;

	if(sink is null)
		sink = (char c) { result ~= c; } ;


	size_t left = str.length % 3;
	size_t i;

	for(i = 0; i < str.length; i += 3)
	{
		sink(Base64Alpahbets[str[i] >> 2]);
		sink(Base64Alpahbets[(str[i] << 6) + (str[i + 1] >> 4)]);
		sink(Base64Alpahbets[(str[i + 1] << 4) + (str[i + 2] >> 6)]);
		sink(Base64Alpahbets[str[i + 2] & 0B00111111]);
	}

	i = str.length - left;
	if(left == 2)
	{
		sink(Base64Alpahbets[str[i] >> 2]);
		sink(Base64Alpahbets[(str[i] << 6) + (str[i + 1] >> 4)]);
		sink(Base64Alpahbets[str[i + 1] << 4]);
		sink('=');
	}
	else if(left == 1) { 
		sink(Base64Alpahbets[str[i] >> 2]);
		sink(Base64Alpahbets[str[i] << 6]);
		sink('='); 
		sink('='); 
	}

	return result;
}

char[] decode(char[] b64, void delegate(char) sink = null)
{
	assert(false, "Not implemented");

	char[] result = null;

	if(sink is null)
		sink = (char c) { result ~= c; } ;

	if(b64.length % 4)
		throw new ArgumentException("Bad Base64 Sequence");

	
	char getDigit(char b64c) {
		foreach(uint i, char c; Base64Alpahbets)	
			if(c == b64c)return cast(char)i;
		throw new ArgumentException("Invalid Base64 Sequence");
	}


	for(size_t i = 0; i < b64.length; i += 4)
	{
		char[4] n = [getDigit(b64[i]), getDigit(b64[i + 1]), 
			getDigit(b64[i + 2]), getDigit(b64[i + 3]) ];

		//sink((n[0] << 2) + (n[1] >> 6));
		//sink((n[1] << 2) + (n[2] 
	}


	return result;
}

}//version(none)
